package com.scorcher.ilink;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;

import android.app.TabActivity;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TabHost;
import android.widget.TabHost.TabSpec;
import android.widget.TextView;

/**
 * This is the main activity that displays during the current application
 * session, this is a tabbed activity that just displays other tabs if u want to
 * add a new tab u can check the setuptab() function of this activity. If u want
 * to add something new to the existing interface, please check out the
 * corresponding tab
 */

public class iLink extends TabActivity implements OnClickListener {

	// debugging
	public static final String TAG = "iLink";
	public static final boolean D = true;

	// Messages sent from ConnectionService handler
	public static final int MESSAGE_SERVER_CONNECTION_INITIATED = 0;
	public static final int MESSAGE_SERVER_NOT_FOUND = 1;
	public static final int MESSAGE_RECEIVING_COMPLETE = 2;
	public static final int MESSAGE_SEND_COMPLETE = 3;
	public static final int UPDATE_PROGRESS = 4;

	// Key names received from ConnectionService
	public static final String TOAST = "toast";
	public static final String FILENAME = "filename";

	// Files to be used to maintain the list of files Available download and
	// upload
	private File localList;
	private File availableDownloadList;

	// Layout Views
	private TextView mTitle;
	private Button butt;
	private EditText textIn;
	private ProgressBar progress;
	private ImageView button;
	private ImageView buttonSelected;

	private int progressStatus = 1;

	private TabHost tabHost;

	// Elements to be transferred in Services
	Socket serverSocket;
	Socket clientSocket;
	DataOutputStream serverData;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		if (D)
			Log.e(TAG, "+++ON CREATE+++");

		if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.ICE_CREAM_SANDWICH)
		{
		}
		// initialize files
		File iLinkFolder = new File(Environment.getExternalStorageDirectory(),
				"iLink");
		if (!iLinkFolder.exists()) {
			boolean result = iLinkFolder.mkdir();
			Log.e(TAG, "" + result);
		}
		
		localList = new File(Environment.getExternalStorageDirectory(),
				"/iLink/list.xml");

		// Set up window layout
		setContentView(R.layout.main);
		textIn = (EditText) findViewById(R.id.FileName);

		// set tab contents
		tabHost = getTabHost();

		// Adding Tabs to TabHost
		setupTextViewTab("Downloading", new Intent(this, Downloading.class));
		setupTextViewTab("Uploading", new Intent(this, Uploading.class));
		setupTextViewTab("File Browser", new Intent(this, FileBrowser.class));

		// Create Xml File Of files available
		Runnable r = new XmlCreater();
		Thread t = new Thread(r);
		t.start();

		// Shall not be used in the next version of the App, there should be a
		// different implementation of these
		// Runnable r = new ClientThread();
		// Thread t = new Thread(r);
		// Runnable sr = new SendThread();
		// Thread send = new Thread(sr);
		// t.start();
		// send.start();
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.activity_main, menu);
		return true;
	}

	/**
	 * Creates a tab in the current activity, using the provided Intent and and
	 * its Tag to be displayed. This function is to be used when creating tabs
	 * using Views
	 * 
	 * @param tag
	 *            {@link String} containing the tag of tab to be set up
	 * @param intent
	 *            {@link Intent} containing the intent of the activity of the
	 *            class to be added in tab
	 */
	private void setupTextViewTab(final String tag, Intent intent) {
		View tabview = createTabView(tabHost.getContext(), tag);
		TabSpec setContent = tabHost.newTabSpec(tag).setIndicator(tabview)
				.setContent(intent);
		tabHost.addTab(setContent);
	}

	/**
	 * 
	 * @param context
	 * @param text
	 * @return Created view that contains the text
	 */
	private static View createTabView(final Context context, final String text) {
		View view = LayoutInflater.from(context)
				.inflate(R.layout.tabs_bg, null);
		TextView tv = (TextView) view.findViewById(R.id.tabsText);
		tv.setText(text);
		return view;
	}

	void connect(InetAddress host, int port) {
		try {
			serverSocket = new Socket(host, port);
			serverData = new DataOutputStream(serverSocket.getOutputStream());
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	void sendXml() {
		FileInputStream fin;
		try {
			serverData.writeUTF(localList.getName());
			serverData.writeLong(localList.length());
			fin = new FileInputStream(localList);
			int data;
			while ((data = fin.read()) != -1) {
				serverData.write(data);
				serverData.flush();
			}
			fin.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	void close() {
		try {
			serverData.close();
			serverSocket.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public class ClientThread implements Runnable {

		public void run() {
			try {
				InetAddress serverAddr = InetAddress.getByName("192.168.14.50");
				connect(serverAddr, 7777);
				sendXml();
			} catch (UnknownHostException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} finally {
				close();
			}
		}
	}

	public class SendThread implements Runnable {
		public void run() {
			ServerSocket sendSocket = null;
			try {
				sendSocket = new ServerSocket(7779);
				while (true) {
					Socket clientSocket = sendSocket.accept();
					DataInputStream readStream = new DataInputStream(
							clientSocket.getInputStream());
					String filename = readStream.readUTF();
					sendFile(filename, clientSocket);
				}
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				try {
					sendSocket.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}

		void sendFile(String file, Socket s) {
			File sfile = new File(Environment.getExternalStorageDirectory(),
					file);
			FileInputStream fin;
			try {
				DataOutputStream sendStream = new DataOutputStream(
						s.getOutputStream());
				DataInputStream recieveStream = new DataInputStream(
						s.getInputStream());
				sendStream.writeLong(sfile.length());
				fin = new FileInputStream(sfile);
				int data;
				byte[] buffer = new byte[4048];
				while ((data = fin.read(buffer)) != -1) {
					if (recieveStream.readUTF().equalsIgnoreCase("ready"))
						;
					sendStream.write(buffer, 0, data);
				}
				sendStream.writeInt(-1);
				fin.close();
				sendStream.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	public class RecieveThread implements Runnable {
		public void run() {
			String fileName = textIn.getText().toString();
			try {
				InetAddress serverAddr = InetAddress
						.getByName("192.168.14.102");
				if (InetAddress.getLocalHost().toString()
						.contains("192.168.14.102"))
					serverAddr = InetAddress.getByName("192.168.14.101");
				Socket peerSocket = new Socket(serverAddr, 7779);
				DataOutputStream peerData = new DataOutputStream(
						peerSocket.getOutputStream());
				peerData.writeUTF(fileName);
				readFile(fileName, peerSocket);
			} catch (UnknownHostException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} finally {
				close();
			}
		}

		private void readFile(String file, Socket s) {

			File rfile = new File(Environment.getExternalStorageDirectory(),
					file);
			try {
				DataInputStream recieveStream = new DataInputStream(
						s.getInputStream());
				DataOutputStream fileStream = new DataOutputStream(
						new FileOutputStream(rfile));
				DataOutputStream sendStream = new DataOutputStream(
						s.getOutputStream());
				int ch1 = 0;
				byte[] buffer = new byte[4048];
				sendStream.writeUTF("ready");
				while ((ch1 = recieveStream.read(buffer)) != -1) {
					fileStream.write(buffer, 0, ch1);
					sendStream.writeUTF("ready");
				}
				fileStream.close();
				recieveStream.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	public void onClick(View v) {
		Runnable r = new RecieveThread();
		Thread recieve = new Thread(r);
		recieve.start();
	}
}